package actions;


import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JOptionPane;

import utils.Constants;
import utils.MessageViewer;
import utils.ParameterValidator;
import utils.RSA_Password;
import client.ClientApplication;
import client.ClientSocketConnection;
import client_gui.ClientWindow;
import client_gui.RegisterDialog;
import client_server.ClientServer;

/**
 * Klasa koja predstavlja akciju Register dugmeta u startup panelu klijenta.
 * Ova klasa je izdvojena od ostalio Action klasa (nasledjuje JButton), jer
 * se objekat ove klase dodaje direktno u JPanel, a ne u JToolBar ili JMenu.
 * 
 * @author UrosKrkic & Radivoje Popovic
 */
public class RegisterAction extends JButton implements ActionListener, Constants {
	/**
	 * Vlasnik akcije.
	 */
	private ClientWindow owner;
	
	private RegisterDialog parent;
	
	
	/**
	 * Konstruktor.
	 * @param owner - vlasnik akcije
	 * @param label - naziv dugmeta
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public RegisterAction(ClientWindow owner, RegisterDialog parent, String label) {
		super(label);
		
		this.setPreferredSize(new Dimension(100,24));
		
		this.setActionOwner(owner);
		
		this.parent = parent;
		
		this.addActionListener(this);
	}
	
	
	
	/**
	 * Metod koji setuje vlasnika ove akcije. Za razliku od klasa akcija, koje
	 * prosiruju RLMAbstarctAction, u LogginAction klasi moguce je pristupiti vlasniku
	 * akcije direktno. Metod je uveden samo zbog ocuvanja doslednosti u interfejsu za
	 * rukovanje akcijama
	 * @param owner - vlasnik aplikacije
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public void setActionOwner(ClientWindow owner) {
		this.owner = owner;
	}
	
	
	
	/**
	 * Metod koji vraca referencu na vlasnika ove akcije. Za razliku od klasa akcija, koje
	 * prosiruju RLMAbstarctAction, u LogginAction klasi moguce je pristupiti vlasniku
	 * akcije direktno. Metod je uvede samo zbog ocuvanja doslednosti u interfejsu za
	 * rukovanje akcijama
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public ClientWindow getActionOwner() {
		return this.owner;
	}
	
	
	
	public void actionPerformed(ActionEvent e) {
		
		parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		
		String username = parent.getUsernameFieldEntry();
		String password = parent.getPasswordFieldEntry();
		String confirmPassword = parent.getConfirmPasswordFieldEntry();
		String nickname = parent.getNicknameFieldEntry();
		String email = parent.getEmailFieldEntry();
		String avatar = parent.getAvatarID();
		
		boolean flag = false;
		
		ParameterValidator.setRegex(ParameterValidator.usernameRegExp);
		flag = ParameterValidator.matchStrings(username);
		if (flag == false) {
			parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			MessageViewer.showError(parent, "Bad or too long Username (max. 15 chars.)");
			return;
		}
		
		ParameterValidator.setRegex(ParameterValidator.passwordRegExp);
		flag = ParameterValidator.matchStrings(password);
		if (flag == false) {
			parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			MessageViewer.showError(parent, "Bad or too long Password (max. 15 chars.)");
			return;
		}
		
		flag = password.equals(confirmPassword);
		if (flag == false) {
			parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			MessageViewer.showError(parent, "Password and Confirmed password must be the same.");
			return;
		}
		
		if (nickname.length() == 0) {
			nickname = "NewUser";
		}
		else {
			ParameterValidator.setRegex(ParameterValidator.nicknameRegExp);
			flag = ParameterValidator.matchStrings(nickname);
			if (flag == false) {
				parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				MessageViewer.showError(parent, "Bad or too long Nickname (max. 15 chars.)");
				return;
			}
		}
		
		if (email.length() == 0) {
			email = "null";
		}
		else {
			ParameterValidator.setRegex(ParameterValidator.mailRegExp);
			flag = ParameterValidator.matchStrings(email, 30);
			if (flag == false) {
				parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				MessageViewer.showError(parent, "Bad e-mail parameter");
				return;
			}
		}
		

		// pokretanje servera ukoliko nije pokrenut
		if ( getActionOwner().getApplicaton().isClientServerRunning() == false ) {
			
			ClientServer clientServer = new ClientServer(getActionOwner().getApplicaton());			
	
			try {
				ClientApplication.clientServerSemaphore.acquire();
				
				getActionOwner().getApplicaton().setClientServer(clientServer);
			}
			catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		
		}
		
		ClientWindow owner = getActionOwner();
		
		if ( owner.getApplicaton().createSocketConnection() == false ) {
			parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			ClientApplication.clientServerSemaphore.release();
			return;
		}
		
		ClientSocketConnection connection = owner.getApplicaton().retrieveSocketConnection();
		
		RSA_Password rsa = new RSA_Password();
		
		StringBuffer buffer = new StringBuffer();
		buffer.append("REG ");
		buffer.append(username);
		buffer.append(" ");
		buffer.append(rsa.codeData(new String(password)));
		buffer.append(" ");
		buffer.append(nickname);
		buffer.append(" ");
		buffer.append(email);
		buffer.append(" ");
		buffer.append(avatar);
		
		String completedRegInfo = buffer.toString();

		connection.setMessage(REG_CMD, completedRegInfo);
	
		String response;
		
		response = connection.buffers[REG_CMD].read();

	
		if ( response.startsWith("220") ) {
			parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			MessageViewer.showError(getActionOwner(), "User already registered.");
			ClientApplication.clientServerSemaphore.release();
			return;
		}
		

		if ( response.startsWith("100") ) {
			owner.setLoginUsername(username);
			owner.setLoginPassword(password);

			parent.dispose();
			
			JOptionPane.showMessageDialog(owner, "Click Login to log in!", "Login", JOptionPane.INFORMATION_MESSAGE);
		}
		
		parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		
		ClientApplication.clientServerSemaphore.release();
	}
	
}
